﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using InTheHand.Net.Bluetooth;
using InTheHand.Net.Sockets;
using InTheHand;
using InTheHand.Windows.Forms;

namespace BlueAd
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
            try
            {
                _comm = new Comm();
                _comm.OnFinish += new EventHandler<Comm.OnDone>(OnFinish);

                _devices = new List<BluetoothDeviceInfo>();

                _scheduler = new Scheduler();
                _scheduler.ActiveCampain += new EventHandler<RunningCampain>(_scheduler_ActiveCampain);
                _scheduler.InactiveCampain += new EventHandler<NotRunningCampain>(_scheduler_InactiveCampain);

                _activeCampains = new List<Campain>();

                _refreshlocker = new object();
                RefreshUiThread = new Thread(RefreshUi);
                RefreshUiThread.Priority = ThreadPriority.BelowNormal;
                RefreshUiThread.Start();
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }

        void _scheduler_InactiveCampain(object sender, NotRunningCampain e)
        {
            Campain campain = sender as Campain;
            if(campain == null) return;

            if (_activeCampains.Contains(campain))
            {
                _activeCampains.Remove(campain);
            }
        }

        void _scheduler_ActiveCampain(object sender, RunningCampain e)
        {
            if(_enabled)
            {
                Campain campain = sender as Campain;
                if (campain == null) return;

                if (!_activeCampains.Contains(campain))
                {
                    _activeCampains.Add(campain);
                }
                _comm.SendCampain(campain);
            }
        }

        private Comm _comm;
        private Scheduler _scheduler;
        private List<BluetoothDeviceInfo> _devices;
        private List<Campain> _activeCampains;
        private readonly object _refreshlocker;
        private delegate void AddDeviceDelegate(BluetoothDeviceInfo deviceInfo);
        private delegate void AddCampainDelegate(Campain campain);
        private Thread RefreshUiThread;
        private bool _enabled = false;

        void OnFinish(object sender, Comm.OnDone e)
        {
            lock (_refreshlocker)
            {
                _devices = sender as List<BluetoothDeviceInfo>;
            }
        }

        public bool Ok { get { return _comm != null; } }

        private void AddDevice(BluetoothDeviceInfo deviceInfo)
        {
            lock (_refreshlocker)
            {
                if (InvokeRequired)
                {
                    Invoke(new AddDeviceDelegate(AddDeviceItem), new object[] { deviceInfo });
                    return;
                }
            }
        }

         private void AddCampain(Campain campain)
         {
             lock (_refreshlocker)
             {
                 if (InvokeRequired)
                 {
                     Invoke(new AddCampainDelegate(AddScheduledCampainItem), new object[] {campain});
                     return;
                 }
             }
         }

        private void AddDeviceItem(BluetoothDeviceInfo deviceInfo)
        {
            if (!_devices.Contains(deviceInfo))
            {
                _devices.Add(deviceInfo);
                lvDevices.Items.Add(deviceInfo.DeviceName);
            }

            lvDevices.Items.Clear();
            foreach (BluetoothDeviceInfo bluetoothDeviceInfo in _devices)
            {
                lvDevices.Items.Add(bluetoothDeviceInfo.DeviceName);
            }
        }

        public void AddScheduledCampainItem(Campain campain)
        {
            if (!clCampains.Items.Contains(campain))
            {
                clCampains.Items.Add(campain);
                _scheduler.Add(campain);
            }

            lvScheduledCampains.Items.Clear();
            foreach (Campain campain1 in _scheduler)
            {
                if (campain1.Enabled && campain1.Start < DateTime.Now && campain1.End > DateTime.Now)
                {
                    //ListViewItem item = lvScheduledCampains.Items.Add(campain1.Name);
                    ListViewItem item = new ListViewItem(campain1.Name);
                    item.SubItems.Add(campain1.Start.ToString());
                    item.SubItems.Add(campain1.End.ToString());
                    lvScheduledCampains.Items.Add(item);
                }
            }
        }


        private void startSearchingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _comm.Start();
        }

        private void stopSearchingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _comm.Stop();
        }

        private void devicesToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
        {
            if (_comm.Listening)
            {
                stopSearchingToolStripMenuItem.Enabled = true;
                startSearchingToolStripMenuItem.Enabled = false;
            }
                
            else
            {
                stopSearchingToolStripMenuItem.Enabled = false;
                startSearchingToolStripMenuItem.Enabled = true;
            }
        }

        private void refreshDevicesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmNewCampain campain = new frmNewCampain(_comm);
            campain.ShowDialog();
            if(campain.DialogResult == System.Windows.Forms.DialogResult.OK)
            {
                if(campain.Campain != null)
                {
                    _scheduler.Add(campain.Campain);
                }
            }
        }

        private void RefreshUi()
        {
            while (_enabled)
            {
                Thread.Sleep(2000);
                lock (_refreshlocker)
                {
                    List<Campain> temp1 = new List<Campain>(_scheduler);
                    foreach (Campain campain in temp1)
                    {
                        AddCampain(campain);
                    }
                    List<BluetoothDeviceInfo> temp2 = new List<BluetoothDeviceInfo>(_devices);
                    foreach (BluetoothDeviceInfo bluetoothDeviceInfo in temp2)
                    {
                        AddDevice(bluetoothDeviceInfo);
                    }
                }
            }
        }

        private void Enable()
        {
            _enabled = true;
            _comm.Start();
            _scheduler.Start();
            if (RefreshUiThread.ThreadState != ThreadState.Running)
            {
                RefreshUiThread = new Thread(RefreshUi);
                RefreshUiThread.Start();
            }
        }

        private void Disable()
        {
            _comm.Stop();
            _scheduler.Stop();
            _enabled = false;
             RefreshUiThread.Abort();
        }

        private void clCampains_ItemCheck(object sender, ItemCheckEventArgs e)
        {

            Campain temp = (sender as CheckedListBox).SelectedItem as Campain;
            if (temp != null)
            {
                if (e.NewValue == CheckState.Checked)
                {
                    temp.Enabled = true;
                }
                else
                {
                    temp.Enabled = false;
                }
            }
        }

        private void chkActive_CheckStateChanged(object sender, EventArgs e)
        {
            if (chkActive.Checked)
                Enable();
            else
                Disable();
        }

        private void clCampains_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (clCampains.SelectedItem != null)
            {
                Campain selected = ((Campain)(sender as ListBox).SelectedItem);

                frmNewCampain campain = new frmNewCampain(_comm, selected);
                campain.ShowDialog();
                if (campain.DialogResult == DialogResult.OK)
                {
                    if (campain.Campain != null)
                    {
                        lock (_refreshlocker)
                        {
                            AddCampain(campain.Campain);
                        }
                    }
                }
            }
        }

        private void exitAppStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void clCampains_MouseClick(object sender, MouseEventArgs e)
        {
            if(e.Button == MouseButtons.Right)
            { 

            }
        }
    }
}
